from colander import null
from deform import widget
from deform.i18n import _

try:
    import json
except ImportError: # PRAGMA: no cover
    import simplejson as json


class HiddenMappingWidget(widget.MappingWidget):
    template = "hidden_mapping"
    item_template = "hidden_mapping_item"


class LicenseCheckboxWidget(widget.CheckboxWidget):
    template = "cc_checkbox"


class RightsForm(widget.FormWidget):
    item_template = "license_item"


class SelectWidget(widget.SelectWidget):
    use_ajax = False


class IFrameWidget(widget.Widget):
    template = "readonly/iframe"
    readonly_template = "readonly/iframe"
    url = ""

    def serialize(self, field, cstruct, readonly=False):
        if cstruct in (null, None):
            cstruct = ''
        template = readonly and self.readonly_template or self.template
        return field.renderer(template, field=field, cstruct=cstruct)

    def deserialize(self, field, pstruct):
        return ""


class SequenceAutocomplete(widget.SequenceWidget,
                           widget.AutocompleteInputWidget):
    error_class = "error"
    template = "autocomplete_sequence"
    item_template = "autocomplete_sequence_item"

    def serialize(self, field, cstruct, readonly=False):
        if (self.render_initial_item and self.min_len is None):
            # This is for compat only: ``render_initial_item=True`` should
            # now be spelled as ``min_len = 1``
            self.min_len = 1

        if cstruct in (null, None):
            if self.min_len is not None:
                cstruct = [null] * self.min_len
            else:
                cstruct = []

        cstructlen = len(cstruct)

        if self.min_len is not None and (cstructlen < self.min_len):
            cstruct = list(cstruct) + ([null] * (self.min_len - cstructlen))

        options = {}
        if not self.delay:
            # set default delay if None
            options['delay'] = (isinstance(self.values,
                                          basestring) and 400) or 10
        options['minLength'] = self.min_length
        options = json.dumps(options)
        values = json.dumps(self.values)

        item_field = field.children[0]

        if getattr(field, 'sequence_fields', None):
            # this serialization is being performed as a result of a
            # validation failure (``deserialize`` was previously run)
            assert(len(cstruct) == len(field.sequence_fields))
            subfields = zip(cstruct, field.sequence_fields)
        else:
            # this serialization is being performed as a result of a
            # first-time rendering
            subfields = [(val, item_field.clone()) for val in cstruct]

        template = readonly and self.readonly_template or self.template
        add_template_mapping = dict(
            subitem_title=item_field.title,
            subitem_description=item_field.description,
            subitem_name=item_field.name)
        add_subitem_text = _(self.add_subitem_text_template,
                             mapping=add_template_mapping)
        return field.renderer(template,
                              field=field,
                              cstruct=cstruct,
                              subfields=subfields,
                              item_field=item_field,
                              add_subitem_text=add_subitem_text,
                              options=options,
                              values=values)


class SequenceBrowserWidget(widget.SequenceWidget):
    template = "sequence_browser"
    item_template = "sequence_browser_dialog"


class PlainTextWidget(widget.TextAreaWidget):
    readonly_template = "readonly/plaintext"

    def serialize(self, field, cstruct, readonly=False):
        if cstruct in (null, None):
            cstruct = ''
        template = readonly and self.readonly_template or self.template
        if readonly:
            cstruct = cstruct.replace('\n', "<br/>")
        return field.renderer(template, field=field, cstruct=cstruct)
